package com.codeckz.library_face.controller

import android.content.Context
import android.graphics.BitmapFactory
import android.graphics.ImageFormat
import android.graphics.Rect
import android.graphics.YuvImage
import android.hardware.usb.UsbDevice
import android.os.Handler
import android.os.HandlerThread
import android.os.Process
import android.util.Log
import android.view.TextureView
import androidx.camera.view.PreviewView
import com.codeckz.library_face.utils.*
import com.lgh.uvccamera.UVCCameraProxy
import com.lgh.uvccamera.bean.PicturePath
import com.lgh.uvccamera.callback.ConnectCallback
import kotlinx.coroutines.*

/**
 *@packageName com.codeckz.library_face.controller
 *@author kzcai
 *@date 2022/1/24
 */
class UseCameraController(private val context: Context,var productId:Int = 0,var vendorId:Int = 0) : ICameraController(),
    CoroutineScope by MainScope() {


    private var previewView: TextureView? = null

    private var mUVCCamera:UVCCameraProxy? = UVCCameraProxy(context)

    private var processThread: HandlerThread? = null
    private var processHandler: Handler? = null
    private var lastFrame:ByteArray?=null


    init {
        processThread = HandlerThread("process")
        processThread!!.priority = 10
        processThread!!.start()
        processHandler = Handler(processThread!!.looper)
    }

    private val processRunnable = java.lang.Runnable {
        if (lastFrame == null) {
            return@Runnable
        }
        Process.setThreadPriority(Process.THREAD_PRIORITY_URGENT_AUDIO)
        var frame: ByteArray?
        var argb: IntArray
        var width: Int
        var height: Int
        synchronized(lastFrame!!) {
            frame = lastFrame

            lastFrame = null
        }

        process(frame!!)
    }

    private fun process(data: ByteArray) {
        val size = mUVCCamera?.previewSize ?: return
        val localYuvImage = YuvImage(data, ImageFormat.NV21, size.width, size.height, null)

        val bitmap = NV21ToBitmap(context).nv21ToBitmap(data,size.width,size.height)
//        val bitmap = localYuvImage.toBitmap()!!

        val cutBm = bitmap.addBitmap(context,circleRect!!)

        if (cutBm != null) {
            if (filterFace == null) {
                filterFace = AndroidFilterFace()
            }
            val result = filterFace!!.checkFace(
                cutBm,
                circleRect!!.bitmapCheckRect(
                    context,
                    cutBm,
                    0
                )
            )
            val newBm = bitmap.cutRectSquareCenter()
            val data = newBm.toByteArray(95)
            onImageAnalysisListener?.invoke(data, result)
            bitmap.recycle()
            cutBm.recycle()
            newBm.recycle()
        }

        bitmap.recycle()
    }


    private fun initCamera() {
        // 已有默认配置，不需要可以不设置
        mUVCCamera?.config
            ?.isDebug(true)
            ?.setDirName("uvccamera")
            ?.setProductId(productId)
            ?.vendorId = vendorId

        mUVCCamera?.setPreviewTexture(previewView)
        mUVCCamera?.setConnectCallback(object : ConnectCallback {
            override fun onAttached(usbDevice: UsbDevice) {
                Log.d("UseCameraController","onAttached")
                mUVCCamera?.requestPermission(usbDevice)
            }

            override fun onGranted(usbDevice: UsbDevice, granted: Boolean) {
                if (granted) {
                    Log.d("UseCameraController","onGranted")
                    mUVCCamera?.connectDevice(usbDevice)
                }
            }

            override fun onConnected(usbDevice: UsbDevice) {
                Log.d("UseCameraController","onConnected")
                mUVCCamera?.openCamera()

            }

            override fun onCameraOpened() {
                Log.d("UseCameraController","onCameraOpened")
//                mUVCCamera.setPreviewSize(640, 480)
                mUVCCamera?.startPreview()

            }

            override fun onDetached(usbDevice: UsbDevice) {
                Log.d("UseCameraController","onDetached")
                mUVCCamera?.closeCamera()
            }
        })

        mUVCCamera?.setPreviewCallback { data ->
            lastFrame = data
            processHandler!!.removeCallbacks(processRunnable)
            processHandler!!.post(processRunnable)
        }
    }

    override fun setPreviewView(view: PreviewView) {

    }

    override fun setPreviewView(view: TextureView) {
        previewView = view
    }

    override fun startCamera() {
        initCamera()
    }

    override fun switchCamera() {

    }

    override fun switchCamera(cameraFacing: Int) {

    }

    override fun release() {
        mUVCCamera?.stopPreview()
        mUVCCamera?.closeCamera()
        mUVCCamera?.getmUVCCamera()?.destroy()
        mUVCCamera = null
    }


}